home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MACSHELL
/
MS1
/
SHELL_SO
/
PATH.C
< prev
next >
Wrap
Text File
|
1992-12-02
|
21KB
|
1,051 lines
/*
* MacShell Source File
*
* Copyright (c) 1989, 1990, 1991, 1992 Suick Bay Technologies. All rights reserved.
*
*
* RESTRICTIONS ON MacShell program and source code.
*
* Ñ╩MacShell¬ is a product of Suick Bay Technologies and is provided for
* restricted use by the owner of the CDROM "Disk to the future II".
*
* Ñ╩No permission is granted for any commercial use without the written
* consent of the Suick Bay Technologies.
*
* Ñ╩No permission is granted for any redistribution of any kind use without
* the written consent of the Suick Bay Technologies.
*
* Ñ╩Permission is granted to use this for any personal noncommercial use.
*
* Ñ╩You may not distribute source or executable code at all, nor may you
* distribute it with or within a commercial product without the written
* consent of the Suick Bay Technologies. Please send modifications to
* the author for inclusion in updates to the program. Thanks.
*
*
* MacShell¬ IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* SUICK BAY TECHNOLOGIES SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY MACSHELL
* OR ANY PART THEREOF.
*
* In no event will Suick Bay Technologies be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Suick Bay Technologies has been advised of the possibility of such damages.
*
* Suick Bay Technologies can be reached at:
*
* 8768 Cottonwood lane
* Maple Grove, MN 55369
* Voice: (612) 425-7025
* AppleLink: D5233
*
*
* No parts of this software may be reproduced or stored in a
* retrieval system or transmitted in any form, or any means,
* electronic, mechanical, photocopying, recording or otherwise,
* without the prior written permission of Suick Bay Technologies.
*
* Spread the word and not the disk.
*
* SPK 030190 : Update for Mac, DOS paths
* SPK 012490 : Fixed FindRoot to send Setvol a PString
* SPK 012290 : Initial
*/
#include <OSUtil.h>
#include "System.h"
#include "Path.h"
#include "Prefs.h"
/*******************************************************************/
char DirSep()
{
char dirChar;
if( ShellPrefs.useMacOSPath )
dirChar = ':';
else if( ShellPrefs.useUNIXPath )
dirChar = '/';
else if( ShellPrefs.useDOSPath )
dirChar = '\\';
return( dirChar );
}
/*******************************************************************/
Boolean ResFileOpen( char *name, int16 vRefNum,
int32 dirID, int16 *refNum )
{
HFileInfo pb;
OSErr err;
char str[ 64 ];
strcpy( str, name );
CtoPstr( str );
pb.ioCompletion = NULL;
pb.ioNamePtr = (StringPtr) str;
pb.ioVRefNum = vRefNum;
pb.ioFDirIndex = 0;
pb.ioDirID = dirID;
err = PBHGetFInfo( &pb, FALSE );
if( err )
return( FALSE );
else if( pb.ioFlAttrib & 0x04 )
{
*refNum = pb.ioFRefNum;
return( TRUE );
}
return( FALSE );
}
/*******************************************************************/
int16 ScanVols( char *pattern )
{
int16 i;
HVolumeParam HPB;
char str[ 64 ];
OSErr err;
for( i = 1; i < 10; i++ )
{
HPB.ioCompletion = NULL;
HPB.ioNamePtr = (StringPtr) str;
HPB.ioVRefNum = 0;
HPB.ioVolIndex = i;
err = PBHGetVInfo( &HPB, FALSE );
if( err == nsvErr )
break;
if( err )
break;
else
{
PtoCstr( str );
if( StrPatMatch( str, pattern ) )
return( HPB.ioVRefNum );
}
}
return( 0 );
}
/*******************************************************************/
OSErr GetIndVolume( int16 whichVol, char *volName,
int16 *volRefNum )
{
HVolumeParam volPB;
OSErr error;
volPB.ioNamePtr = (StringPtr) volName;
volPB.ioVRefNum = 0;
volPB.ioVolIndex = whichVol;
error = PBHGetVInfo(&volPB,false);
if( error == noErr )
*volRefNum = volPB.ioVRefNum;
return(error);
}
/*******************************************************************
* Convert a Mac Pathname to a UNIX pathname
*******************************************************************/
Boolean isMacName( char c )
{
return( isPrint( c ) && c != ':' );
}
void _MacToUNIXPath( char *path )
{
char tpath[ 256 ], *cp, *tp;
Boolean subDirs = FALSE, fullPath = FALSE;
cp = path;
tp = tpath;
if( *cp == ':' ) /* partial pathname */
*cp++;
else
{
*tp++ = '/';
*tp++ = '/';
fullPath = TRUE;
}
while( *cp )
{
while( isMacName( *cp ) )
*tp++ = *cp++;
if( *cp == ':' ) /* convert dir */
{
if( *(cp+1) ) /* not end of path */
*tp++ = '/';
*cp++;
}
else /* some weird character */
*tp++ = *cp++;
}
*tp = *cp;
strcpy( path, tpath );
}
void _MacToDOSPath( char *path )
{
char tpath[ 256 ], *cp, *tp;
Boolean subDirs = FALSE, fullPath = FALSE;
cp = path;
tp = tpath;
if( *cp == ':' ) /* partial pathname */
*cp++;
else /* full path */
{
while( (*cp != ':') && *cp ) /* copy vol name */
*tp++ = *cp++;
if( *cp )
{
*tp++ = *cp++;
*tp++ = '\\';
}
else
{
*tp++ = ':';
*tp++ = '\\';
*tp = '\0';
}
}
while( *cp )
{
while( isMacName( *cp ) )
*tp++ = *cp++;
if( *cp == ':' ) /* convert dir */
{
if( *(cp+1) ) /* not end of path */
*tp++ = '\\';
*cp++;
}
else /* some weird character */
*tp++ = *cp++;
}
*tp = *cp;
strcpy( path, tpath );
}
void _MacToMacPath( char *path )
{
char tpath[ 256 ], *cp, *tp;
cp = path;
tp = tpath;
#ifdef FALSE
if( *cp == ':' ) /* partial pathname */
*cp++;
while( *cp )
{
if( *cp == ':' ) /* path */
break;
cp++;
}
#endif
if( *cp == ':' ) /* in this dir */
{
cp = path;
cp++;
strcpy( tpath, cp );
strcpy( path, tpath );
}
}
void MacToPath( char *path )
{
if( ShellPrefs.useMacOSPath )
_MacToMacPath( path );
else if( ShellPrefs.useUNIXPath )
_MacToUNIXPath( path );
else if( ShellPrefs.useDOSPath )
_MacToDOSPath( path );
}
/*******************************************************************/
char scanPath[ 256 ];
char lastScan[ 64 ];
pathType ScanDir( char *lookFor, int16 *vRefNum, int32 *dirID, int32 *parDirID )
{
int16 i, numEntries;
OSErr err;
CInfoPBRec localPB;
/*
* Get the number of items in this directory
*/
localPB.dirInfo.ioFDirIndex = -1; /* this directory */
localPB.dirInfo.ioCompletion = NULL;
localPB.dirInfo.ioNamePtr = NULL;
localPB.dirInfo.ioVRefNum = *vRefNum;
localPB.dirInfo.ioDrDirID = *dirID;
err = PBGetCatInfo( &localPB, FALSE );
numEntries = localPB.dirInfo.ioDrNmFls;
/*
printf( "scan dir for %s vref %d dirID %ld\n",
lookFor, *vRefNum, *dirID );
*/
for(i = 1; i <= numEntries; i++)
{
localPB.hFileInfo.ioFDirIndex = i;
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioNamePtr = (StringPtr) lastScan;
localPB.hFileInfo.ioVRefNum = *vRefNum;
localPB.hFileInfo.ioDirID = *dirID;
err = PBGetCatInfo( &localPB, FALSE);
/*
printf( " %3d : %ps\n", i, lastScan );
*/
if( err == fnfErr )
break;
if( err || UserAbort() )
break;
PtoCstr( lastScan );
if( StrPatMatch( lastScan, lookFor ) )
{
if( localPB.hFileInfo.ioFlAttrib & 0x10 )
{
*dirID = localPB.hFileInfo.ioDirID;
return( pathIsDir );
}
else
return( pathIsFile );
}
}
return( pathDNExist );
}
/*******************************************************************/
void GetDirSize( char *path, int16 vRefNum, int32 dirID, int32 *size )
{
int16 i, numEntries;
OSErr err;
CInfoPBRec localPB;
char str[ 256 ];
/*
* Get the number of items in this directory
*/
localPB.dirInfo.ioFDirIndex = 0; /* this directory */
localPB.dirInfo.ioCompletion = NULL;
localPB.dirInfo.ioNamePtr = (StringPtr) path;
localPB.dirInfo.ioVRefNum = vRefNum;
localPB.dirInfo.ioDrDirID = dirID;
err = PBGetCatInfo( &localPB, FALSE );
numEntries = localPB.dirInfo.ioDrNmFls;
dirID = localPB.dirInfo.ioDrDirID;
for( i = 1; i<= numEntries; i++ )
{
if( UserAbort() )
break;
localPB.hFileInfo.ioFDirIndex = i;
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioNamePtr = (StringPtr) path;
localPB.hFileInfo.ioVRefNum = vRefNum;
localPB.hFileInfo.ioDirID = dirID;
err = PBGetCatInfo( &localPB, FALSE);
if( err )
break;
if( localPB.hFileInfo.ioFlAttrib & 0x10 )
GetDirSize( path, vRefNum, localPB.hFileInfo.ioDirID, size );
else
*size += localPB.hFileInfo.ioFlLgLen + localPB.hFileInfo.ioFlRLgLen;
}
}
/*******************************************************************/
OSErr GetParID( int16 vRefNum, int32 dirID, int32 *parDirID )
{
CInfoPBRec localPB;
OSErr err;
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioResult = 0;
localPB.hFileInfo.ioNamePtr = 0;
localPB.hFileInfo.ioVRefNum = vRefNum;
localPB.hFileInfo.ioFDirIndex =-1;
localPB.hFileInfo.ioDirID = dirID;
err = PBGetCatInfo (&localPB ,FALSE);
*parDirID = localPB.hFileInfo.ioFlParID;
return( err );
}
OSErr GetDirName( int16 vRefNum, int32 dirID, char *name )
{
CInfoPBRec localPB;
OSErr err;
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioResult = 0;
localPB.hFileInfo.ioNamePtr = (StringPtr) name;
localPB.hFileInfo.ioVRefNum = vRefNum;
localPB.hFileInfo.ioFDirIndex = -1;
localPB.hFileInfo.ioDirID = dirID;
err = PBGetCatInfo (&localPB ,FALSE);
return( err );
}
/*******************************************************************
* Get information about the current directory
*
* Volume Ref Number
* Directory ID
* Parent Dir ID
*******************************************************************/
OSErr GetPWDInfo( int16 *vRefNum, int32 *dirID, int32 *parDirID )
{
OSErr err;
CInfoPBRec localPB;
char str[ 64 ];
err = HGetVol( str, vRefNum, dirID );
if( err == noErr )
{
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioResult = 0;
localPB.hFileInfo.ioNamePtr = 0;
localPB.hFileInfo.ioVRefNum = *vRefNum;
localPB.hFileInfo.ioFDirIndex =-1;
localPB.hFileInfo.ioDirID = *dirID;
err = PBGetCatInfo (&localPB ,FALSE);
*parDirID = localPB.hFileInfo.ioFlParID;
}
#ifdef RDB
printf( "GetPWDInfo vRefNum %d dirID %ld parDirID %ld\n",
*vRefNum, *dirID, *parDirID );
#endif
return( err );
}
/*******************************************************************/
OSErr SetWD( int16 vRefNum, int32 dirID )
{
OSErr err;
#ifdef RDB
printf( "SetWD vRefNum %d dirID %ld\n",
vRefNum, dirID );
#endif
err = HSetVol( NULL, vRefNum, dirID );
return( err );
}
/*******************************************************************
*
* This function moves through a path name looking for the
* end of the path, it returns what it found, if it found it.
*
*******************************************************************/
pathType SetDirPath( char *path, int16 *vRefNum, int32 *dirID,
int32 *parDirID )
{
char buf[256];
int16 i=0;
pathType pt;
OSErr err;
if( *path == '\0' )
return( pathIsDir );
if( *path == ':')
{
if( *(path+1) == ':' )
while( *path == ':' && *(path+1) == ':' )
{
SetWD( *vRefNum, *parDirID );
GetPWDInfo( vRefNum, dirID, parDirID );
path++;
path++;
}
else
path++;
}
else
return( pathDNExist );
if( *path =='\0')
return( pathIsDir );
while( (*path != ':') && *path)
buf[i++] = *path++;
buf[i] = '\0';
pt = ScanDir( buf, vRefNum, dirID, parDirID );
switch( pt )
{
case pathDNExist :
break;
case pathIsFile :
break;
case pathIsDir :
SetWD( *vRefNum, *dirID );
break;
}
if( *path =='\0')
return( pt );
else
return( SetDirPath( path, vRefNum, dirID, parDirID ) );
}
/*******************************************************************/
void _UNIXToMac( char *path, Boolean *neededVol, Boolean *goToRoot,
char *volName )
{
char buf[256], /* buffer for storing dir names */
*dirbuf[ MAX_DIR ], /* pointers to directory names */
*cp, /* temp pointer */
*pathBase; /* temp pointer */
int16 i = 0,
d = 0,
root = 0,
c = 0;
pathBase = cp = path;
*neededVol = FALSE;
*goToRoot = FALSE;
while( *cp == '/') /* look for root and volume spec */
{
cp++; /* root=0 then partial path */
root++; /* root=1 then full pathname */
} /* root=2 then vol specifier */
while ( *cp ) /* look for directories */
{
while( *cp == '/') /* ??? Dan Code */
cp++;
if( *cp )
{
dirbuf[ d ] = &(buf[ i ]);
while ( *cp && (*cp != '/'))
{
if( *cp == '\\')
{
buf[ i++ ] = *cp++;
break;
}
else
buf[ i++ ] = *cp++;
}
buf[ i++ ] = '\0';
d++;
if( d > MAX_DIR )
break;
} /* End if */
} /* End while ( *cp) */
switch( root )
{
case 0 : /* partial */
*path++ = ':';
break;
case 1 : /* root dir */
*goToRoot = TRUE;
if (d > 0)
*path++=':';
break;
case 2 : /* volume */
*neededVol = TRUE;
if( d > 1 )
{
c = 1;
*path++=':';
}
else if( d == 1 )
{
c = 1;
*path = '\0';
}
break;
}
if( *neededVol && ( d < 1 ))
{
*path = '\0';
}
else
{
for( i = c; i < d; i++ )
{
#ifdef MYDEBUG
printf( "%d '%s'\n", i, dirbuf[i] );
#endif
if( (strcmp(dirbuf[i], "..") == 0))
*path++ = ':';
else if ( strcmp( dirbuf[i], "\\") == 0)
{
*path++ = ':';
if( i>0 )
*path++ = ':';
}
else if( strcmp(dirbuf[i], ".") == 0)
continue;
else
{
cp = dirbuf[i];
while( *path++ = *cp++ );
path--;
if( i< (d-1) )
*path++=':';
}
}
*path++ = '\0';
#ifdef MYDEBUG
printf("The current path name is %s\n",pathBase);
#endif
if( *neededVol )
strcpy( volName, dirbuf[ 0 ] );
}
}
void _DOSToMac( char *path, Boolean *neededVol, Boolean *goToRoot,
char *volName )
{
char buf[256], /* buffer for storing dir names */
*dirbuf[ MAX_DIR ], /* pointers to directory names */
*cp, /* temp pointer */
*pathBase; /* temp pointer */
int16 i = 0,
d = 0,
partial = FALSE,
c = 0;
pathBase = cp = path;
*neededVol = FALSE;
*goToRoot = FALSE;
/*
* Dave: volume
* Dave:\blah\blab full path
* \blah\blab full path
* blah dir
* blah\blab partial path
* blab file
*/
if( *cp == '\\')
{
cp++;
*goToRoot = TRUE;
partial = TRUE;
}
else /* could be a volume */
{
char *vp, *save;
save = cp;
vp = volName;
while( (*cp != '\\') && (*cp != ':') && *cp )
*vp++ = *cp++;
if( *cp == ':' ) /* found volume */
{
*vp = '\0';
*neededVol = TRUE;
}
/* partial path */
cp = save;
partial = TRUE;
}
while( *cp )
{
while( *cp == '\\')
cp++;
if( *cp )
{
dirbuf[ d ] = &(buf[ i ]);
while ( *cp && (*cp != '\\'))
{
if( *cp == '\\') /* dir specifier */
{
buf[ i++ ] = *cp++;
break;
}
else if( *cp == ':' ) /* volume spec */
{
cp++; /* yooo here */
}
else
buf[ i++ ] = *cp++;
}
buf[ i++ ] = '\0';
d++;
if( d > MAX_DIR )
break;
} /* End if */
} /* End while ( *cp) */
if( *neededVol && ( d < 1 ))
{
*path = '\0';
}
else
{
if( partial )
*path++ = ':';
for( i = c; i < d; i++ )
{
if( (strcmp(dirbuf[i], "..") == 0))
*path++ = ':';
else if ( strcmp( dirbuf[i], "\\") == 0)
{
*path++ = ':';
if( i>0 )
*path++ = ':';
}
else if( strcmp(dirbuf[i], ".") == 0)
continue;
else
{
cp = dirbuf[i];
while( *path++ = *cp++ );
path--;
if( i< (d-1) )
*path++=':';
}
}
*path++ = '\0';
}
}
void _MacToMac( char *path, Boolean *neededVol, Boolean *goToRoot,
char *volName )
{
char *cp, *vp;
cp = path;
*neededVol = FALSE;
*goToRoot = FALSE;
if( *cp != ':' ) /* file or full pathname */
{
while( *cp )
{
if( *cp == ':' )
break;
cp++;
}
if( *cp == ':' ) /* full path */
{
cp = path;
vp = volName;
while( (*cp != ':') && *cp ) /* vol name */
*vp++ = *cp++;
*vp = '\0';
if( *cp ) /* copy : and path */
{
vp = path;
while( *cp )
*vp++ = *cp++;
*vp = '\0';
}
*neededVol = TRUE;
}
else /* file */
{
char buf[ 256 ];
strcpy( buf, path );
strcpy( path, ":" );
strcat( path, buf );
}
}
}
/********************************************************************/
Boolean FindRoot()
{
OSErr err;
char buf[ 255 ];
char name[ 64 ], *cp;
int16 i=0;
int16 MyVolRefNum, newVolRefNum;
GetCurrPath( buf );
cp = buf;
while( *cp == '/' )
cp++;
while ( *cp && (*cp != '/'))
name[ i++ ] = *cp++;
name[ i++ ] = '\0';
cp = name;
i=1;
newVolRefNum = 0;
while ( GetIndVolume(i++, buf , &MyVolRefNum) != nsvErr )
{
PtoCstr( buf );
if( strcmp( buf , name ) == 0 )
newVolRefNum = MyVolRefNum;
}
CtoPstr( name );
err = SetVol( (StringPtr) cp, newVolRefNum );
if( err )
return ( FALSE );
else
return( TRUE );
}
/*******************************************************************
*
*******************************************************************/
Boolean ChangeVol( char *newVolName )
{
int16 vRefNum, err;
WDPBRec WDR;
#ifdef MYDEBUG
printf("Entered Change Vol\n");
#endif
vRefNum = ScanVols( newVolName );
if( vRefNum )
{
err = SetVol( NULL, vRefNum );
if( !err )
return( TRUE );
}
return( FALSE );
}
/*******************************************************************
* Set the current path
* If the unix flag is true then the path is a
* UNIX path, else it is a Mac path
* return any OsErr.
*******************************************************************/
pathType SetCurrPath( char *path )
{
int16 vRefNum;
int32 dirID, parDirID;
char newVolName[ 64 ], buf[ 256 ];
Boolean neededVol,goToRoot,foundLastDir;
#ifdef RDB
GetPWDInfo( &vRefNum, &dirID, &parDirID );
printf( "SetCurrPath vRef %d dirID %ld START\n", vRefNum, dirID );
#endif
scanPath[ 0 ] = '\0';
strcpy( buf, path );
if( ShellPrefs.useMacOSPath )
_MacToMac( buf, &neededVol, &goToRoot, newVolName );
else if( ShellPrefs.useUNIXPath )
_UNIXToMac( buf, &neededVol, &goToRoot, newVolName );
else if( ShellPrefs.useDOSPath )
_DOSToMac( buf, &neededVol, &goToRoot, newVolName );
if( goToRoot )
{
if( FindRoot() )
{
GetPWDInfo( &vRefNum, &dirID, &parDirID );
return( SetDirPath( buf, &vRefNum, &dirID, &parDirID) );
}
}
GetPWDInfo( &vRefNum, &dirID, &parDirID );
#ifdef RDB
printf( "SetCurrPath vRef %d dirID %ld\n", vRefNum, dirID );
#endif
if( neededVol )
{
if( ChangeVol( newVolName ) == FALSE ) /* no volume */
return( nsvErr );
GetPWDInfo( &vRefNum, &dirID, &parDirID );
}
return( SetDirPath( buf, &vRefNum, &dirID, &parDirID) );
}
/*******************************************************************
* Get the current path
* if unix flag is TRUE then return UNIX path
* else return Mac pathname
*******************************************************************/
OsErr GetMacPathFrom( int16 vRefNum, int32 dirID, char *buf )
{
char temp[ 256 ];
char path[ 256 ], *cp;
int32 parDirID;
CInfoPBRec localPB;
int16 i = 0, err, j;
localPB.hFileInfo.ioCompletion = NULL;
localPB.hFileInfo.ioNamePtr = (StringPtr) buf;
localPB.hFileInfo.ioVRefNum = vRefNum;
localPB.hFileInfo.ioDirID = dirID;
localPB.hFileInfo.ioFDirIndex = -1;
localPB.hFileInfo.ioResult = 0;
strcpy( path, "" );
while( !localPB.hFileInfo.ioResult )
{
localPB.hFileInfo.ioCompletion = NULL;
PBGetCatInfo( &localPB, FALSE );
if( localPB.hFileInfo.ioResult == fnfErr )
break;
PtoCstr( buf );
if( i > 0 )
strcat( buf, ":" );
strcat( buf, path );
strcpy( path, buf );
localPB.hFileInfo.ioDirID = localPB.hFileInfo.ioFlParID;
localPB.hFileInfo.ioFDirIndex = -1;
i++;
}
strcpy( buf, path );
if( localPB.hFileInfo.ioResult != fnfErr )
return( localPB.hFileInfo.ioResult );
else
return( noErr );
}
/*******************************************************************/
OsErr GetPathFrom( int16 vRefNum, int32 dirID, char *buf )
{
OsErr err;
err = GetMacPathFrom( vRefNum, dirID, buf );
MacToPath( buf );
return( err );
}
OsErr GetCurrPath( char *buf )
{
int16 vRefNum, err;
int32 dirID, parDirID;
GetPWDInfo( &vRefNum, &dirID, &parDirID );
err = GetPathFrom( vRefNum, dirID, buf );
return( err );
}
OsErr GetCurrMacPath( char *buf )
{
int16 vRefNum;
int32 dirID, parDirID;
GetPWDInfo( &vRefNum, &dirID, &parDirID );
return( GetMacPathFrom( vRefNum, dirID, buf ) );
}
/*******************************************************************/
char *GetLastScan()
{
return( lastScan );
}